home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Emulators / v2600 / Source.lha / Source / amiga_disp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-25  |  10.0 KB  |  461 lines

  1. /*****************************************************************************
  2. Author     : Matthew Stroup
  3. Description: Amiga graphics output for v2600 Atari 2600 emulator
  4. Version    : 2.0 Feb 5, 1997
  5. ******************************************************************************/
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "types.h"
  11. #include "config.h"
  12. #include "vmachine.h"
  13. #include "colours.h"
  14. #include "keyboard.h"
  15. #include "options.h"
  16. #include "display.h"
  17. #include <exec/types.h>
  18. #include <exec/memory.h>
  19. #include <intuition/intuition.h>
  20. #include <graphics/gfxmacros.h>
  21. #include <graphics/display.h>
  22. #include <proto/exec.h>
  23. #include <proto/graphics.h>
  24. #include <proto/intuition.h>
  25. #include <hardware/custom.h>
  26. #include <hardware/cia.h>
  27.  
  28. /*****************************************************************************/
  29.  
  30. void __asm chunky2planar(register __a0 UBYTE *chunky, register __a1 PLANEPTR raster);
  31.  
  32. void __asm c2p8_init (    register __a0 UBYTE *chunky,        // pointer to chunky data
  33.                         register __a1 UBYTE *chunky_cmp,    // pointer to chunky comparison buffer
  34.                         register __a2 PLANEPTR *planes,        // pointer to planes
  35.                         register __d0 ULONG signals1,        // 1 << sigbit1
  36.                         register __d1 ULONG signals2,        // 1 << sigbit2
  37.                         register __d2 ULONG pixels,            // WIDTH * HEIGHT
  38.                         register __d3 ULONG offset,            // byte offset into plane
  39.                         register __d4 UBYTE *buff2,            // Chip buffer (size = width*height)
  40.                         register __d5 UBYTE *buff3,            // Chip buffer (size = width*height)
  41.                         register __a3 struct GfxBase *GfxBase);
  42.  
  43. void __asm c2p8_go(void);
  44.  
  45. long get_signals(void);
  46. void free_signals(void);
  47. long get_chunky_mem(void);
  48. void free_chunky_mem(void);
  49. void init_chunky(void);
  50. long get_window(void);
  51.  
  52. UBYTE *chunky_cmp=0;    // chunky data comparison buffer (preferably in fast ram)
  53. UBYTE *buff2=0;        // blitter buffer (chip ram)
  54. UBYTE *buff3=0;        // blitter buffer (chip ram)
  55.  
  56. long sigbit1 = -1;        // used by c2p8()
  57. long sigbit2 = -1;        // used by c2p8()
  58.  
  59. struct Screen *scr=0;
  60. struct Window *win=0;
  61. struct RastPort *rp=0, temprp;
  62. struct ViewPort *vp=0;
  63. struct IntuiMessage *message=0;
  64. struct GfxBase *GfxBase=0;
  65. struct IntuitionBase *IntuitionBase=0;
  66.  
  67. struct TagItem TagArray[] = {
  68.     // can add other tags here
  69.     TAG_DONE,0
  70. };
  71.  
  72. char perm[8] = {0, 1, 2, 3, 4, 5, 6, 7};    // bitplane order
  73.  
  74. PLANEPTR raster=0, temprast=0;        // 8 contiguous bitplanes
  75. struct BitMap bitmap_bm, tempbm;    // The full depth-8 bitmap
  76.  
  77. struct ExtNewScreen NewScreenStructure = {
  78.     0,0,
  79.     320,200,
  80.     7,
  81.     0,1,
  82.     NULL,
  83.     CUSTOMSCREEN+CUSTOMBITMAP+SCREENQUIET+NS_EXTENDED,
  84.     NULL,
  85.     NULL,
  86.     NULL,
  87.     &bitmap_bm,
  88.     (struct TagItem *)&TagArray
  89. };
  90.  
  91. struct NewScreen ns = {
  92.     0,0,                                // Left edge, Right edge
  93.     320,200,7,                        // Width, Height, Depth
  94.     1,2,                                // Detail pen, block pen
  95.     SPRITES,                            // Display modes
  96.     CUSTOMSCREEN,                        // Type
  97.     NULL,                            // Font
  98.     NULL,                            // Title
  99.     NULL,                            // Gadgets
  100.     NULL                                // Custom Bitmap
  101.     };
  102.  
  103. struct NewWindow NewWindowStructure1 = {
  104.     0,0,
  105.     320,200,
  106.     0,1,
  107.     NULL,
  108.     SIMPLE_REFRESH+BORDERLESS+NOCAREREFRESH,
  109.     NULL,
  110.     NULL,
  111.     NULL,
  112.     NULL,
  113.     NULL,
  114.     0,0,
  115.     0,0,
  116.     CUSTOMSCREEN
  117. };
  118.  
  119. /* Start of image data */
  120. UBYTE *vscreen=0;
  121.  
  122. /* The width and height of the image, including any magnification */
  123. int vwidth, vheight, theight;
  124.  
  125. /* The frame rate counter. Used by the -rr switch */
  126. int tv_counter = 0;
  127.  
  128. /* Optionally set by the X debugger. */
  129. int redraw_flag = 1;
  130.  
  131. static int bytesize;
  132.  
  133. long get_screen(void);
  134.  
  135. UBYTE colors[NUMCOLS];
  136.  
  137. extern int moudrv_x, moudrv_y, moudrv_but;
  138.  
  139.  
  140. #define CIAAPRA 0xBFE001
  141.  
  142. struct CIA *ciamou = (struct CIA *) CIAAPRA;
  143.  
  144. /*****************************************************************************/
  145.  
  146. /* Turns on the television. */
  147. /* returns: 1 for success, 0 for failure */
  148. int tv_on (int argc, char **argv)
  149. {
  150. int i;
  151.  
  152.     // Make sure necessary ROM libraries are open
  153.     IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0);
  154.     if (IntuitionBase == NULL) return(0);    
  155.  
  156.     GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",0);
  157.     if (GfxBase == NULL) return(0);
  158.  
  159.     if (Verbose) printf ("OK\n  Allocating screen buffer...");
  160.  
  161.     vscreen = (UBYTE *) AllocMem (64000, MEMF_PUBLIC|MEMF_CLEAR);
  162.  
  163.     if (!vscreen)
  164.     {
  165.         if (Verbose) printf ("Memory Allocation FAILED\n");
  166.         return (0);
  167.     }
  168.  
  169.     if (base_opts.video==1)
  170.     {
  171.         if ((win=OpenWindowTags(NULL,
  172.                             WA_Title, "Amiga v2600",
  173.                             WA_AutoAdjust,TRUE,
  174.                             WA_InnerWidth, 320, 
  175.                             WA_InnerHeight, 192,
  176.                             WA_DragBar, TRUE,
  177.                             WA_CloseGadget, TRUE,
  178.                             WA_DepthGadget,TRUE,
  179.                             WA_GimmeZeroZero, TRUE,
  180.                             WA_SmartRefresh, TRUE,
  181.                             WA_IDCMP,IDCMP_CLOSEWINDOW,
  182.                             TAG_DONE))==NULL) return(0);
  183.  
  184.         for (i=0; i<NUMCOLS; i++)
  185.         {
  186.             colors[i]=ObtainBestPen(win->WScreen->ViewPort.ColorMap,
  187.                         (colortable[i*2] & 0xff0000)<<8,
  188.                         (colortable[i*2] & 0x00ff00)<<16,
  189.                         (colortable[i*2] & 0x0000ff)<<24,
  190.                         OBP_Precision,PRECISION_EXACT,
  191.                         TAG_DONE);
  192.         }
  193.         rp=win->RPort;
  194.         InitBitMap(&tempbm, 8, 320, 200);
  195.         if ((temprast=(PLANEPTR)AllocRaster(320, 8*200))==NULL) return (0);
  196.         for(i=0; i<8; i++)
  197.         {
  198.             tempbm.Planes[i] = temprast + (perm[i] * RASSIZE (320, 200));
  199.         }
  200.         InitRastPort(&temprp);
  201.         temprp.BitMap=&tempbm;
  202.     }
  203.     else
  204.     {
  205.         if (get_screen()==0) return(0);
  206.         ShowTitle(scr, 0);
  207.         for (i=0; i<NUMCOLS; i++)
  208.         {
  209.             SetRGB32(&scr->ViewPort,i,
  210.                     (colortable[i*2] & 0xff0000)<<8,
  211.                     (colortable[i*2] & 0x00ff00)<<16,
  212.                     (colortable[i*2] & 0x0000ff)<<24);
  213.             colors[i]=i;
  214.         }
  215.         if (base_opts.video==2)
  216.         {
  217.             if(get_chunky_mem()==0) return(0);
  218.             if(get_signals())
  219.             {
  220.                 NewWindowStructure1.Screen = scr;
  221.                 if (get_window()==0) return(0);
  222.                 // initialize c2p converter
  223.                 c2p8_init (    vscreen,
  224.                             chunky_cmp,
  225.                             &rp->BitMap->Planes[0],
  226.                             1 << sigbit1,
  227.                             1 << sigbit2,
  228.                             64000,
  229.                             0,
  230.                             buff2,
  231.                             buff3,
  232.                             GfxBase);
  233.             }
  234.             else return(0);
  235.         }
  236.     }
  237.  
  238.     bytesize = 64000;
  239.  
  240.     /* Calculate the video width and height */
  241.     vwidth = tv_width * 2;
  242.     theight = tv_height + 8;
  243.     vheight = theight;
  244.  
  245.     /* Turn on the keyboard. Must be done after toplevel is created */
  246.     init_keyboard();
  247.  
  248.     if (Verbose) printf ("OK\n\b");
  249.     return (1);
  250. }
  251.  
  252. /*****************************************************************************/
  253.  
  254. /* Turn off the tv. Closes the X connection and frees the shared memory */
  255. void tv_off (void)
  256. {
  257.     if (Verbose) printf ("Switching off...\n");
  258.  
  259.     if (base_opts.video==2)
  260.     {
  261.         free_chunky_mem();
  262.         free_signals();
  263.     }
  264.  
  265.     if (base_opts.video!=0)
  266.     {
  267.         if (win) CloseWindow(win);
  268.     }
  269.  
  270.     if (base_opts.video==1)
  271.     {
  272.         if (temprast) FreeRaster (temprast, 320, 8*200);
  273.     }
  274.     else
  275.     {
  276.         if (scr) CloseScreen(scr);
  277.         if (raster) FreeRaster (raster, 320, 8 * 200);
  278.     }
  279.  
  280.     if (vscreen) FreeMem(vscreen, 64000);
  281.     if (GfxBase) CloseLibrary((struct Library *)GfxBase);
  282.     if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  283. }
  284.  
  285. /*****************************************************************************/
  286.  
  287. /* Displays the tv screen */
  288. void tv_display (void)
  289. {
  290.     /* Only display if the frame is a valid one. */
  291.     if (tv_counter % base_opts.rr == 0)
  292.     {
  293.         switch(base_opts.video)
  294.         {
  295.             case 0:
  296.                 WaitBOVP(&scr->ViewPort);
  297.                 chunky2planar(vscreen,raster);
  298.                 break;
  299.             case 1:
  300.                 WritePixelArray8(rp, 0, 0, 319, 191, vscreen, &temprp);
  301.                 if (message=(struct IntuiMessage *)GetMsg(win->UserPort))
  302.                 {
  303.                     if (message->Class==CLOSEWINDOW) exit(0);
  304.                 }
  305.                 break;
  306.             case 2:
  307.                 c2p8_go();
  308.         }
  309.     }
  310.     tv_counter++;
  311. }
  312.  
  313. /*****************************************************************************/
  314.  
  315. /* The Event code. */
  316. void tv_event (void)
  317. {
  318.     read_keyboard();
  319. }
  320.  
  321. /*****************************************************************************/
  322.  
  323. UBYTE tv_color (UBYTE b)
  324. {
  325.     return (UBYTE)(b >> 1);
  326. }
  327.  
  328. /*****************************************************************************/
  329.  
  330. long get_screen(void)
  331. {
  332.     long depth, ok = 0;
  333.  
  334.     InitBitMap(&bitmap_bm, 8, 320, 200);    // Full depth-8 bm
  335.  
  336.     // since c2p_020() needs 8 contiguous bitplanes, it is not
  337.     // possible to just use OpenScreen() or AllocBitmap() as they
  338.     // may give the bitplanes in a few chunks of memory (noncontiguous)
  339.  
  340.     if( raster = (PLANEPTR)AllocRaster (320, 8 * 200))
  341.     {
  342.         for(depth = 0; depth < 8; depth++)
  343.         {
  344.             bitmap_bm.Planes[depth] = raster + (perm[depth] * RASSIZE (320, 200));
  345.         }
  346.         
  347.         if(scr = OpenScreen( (struct NewScreen *) &NewScreenStructure))
  348.         {
  349.             SetRast(&scr->RastPort, 0);        // clear screen memory
  350.             WaitBlit();                    // wait until it's finished
  351.     
  352.             ok = 1;
  353.         }
  354.     }
  355.  
  356.     return(ok);
  357.  
  358. }
  359.  
  360. /*****************************************************************************/
  361.  
  362. void free_chunky_mem(void)
  363. {
  364.     if(buff3)
  365.         FreeVec(buff3);
  366.  
  367.     if(buff2)
  368.         FreeVec(buff2);
  369.  
  370.     if(chunky_cmp)
  371.         FreeVec(chunky_cmp);
  372. }
  373.  
  374. /*****************************************************************************/
  375.  
  376. void free_signals(void)
  377. {
  378.     if(sigbit1 != -1)
  379.     {
  380.         Wait (1 << sigbit1);    // wait for last c2p8 to finish pass 3
  381.         FreeSignal(sigbit1);
  382.         sigbit1 = -1;
  383.     }
  384.  
  385.     if(sigbit2 != -1)
  386.     {
  387.         Wait (1 << sigbit2);    // wait for last c2p8 to finish totally
  388.         FreeSignal(sigbit2);
  389.         sigbit2 = -1;
  390.     }
  391. }
  392.  
  393. /*****************************************************************************/
  394.  
  395. long get_chunky_mem(void)
  396. {
  397.     if((chunky_cmp = AllocVec(64000, MEMF_CLEAR+MEMF_ANY))==0) return (0);
  398.     if((buff2 = AllocVec(64000, MEMF_CLEAR+MEMF_CHIP))==0) return (0);
  399.     if((buff3 = AllocVec(64000, MEMF_CLEAR+MEMF_CHIP))==0) return (0);
  400.     return(1);
  401. }
  402.  
  403. /*****************************************************************************/
  404.  
  405. long get_signals(void)
  406. {
  407.     long ok = 0;
  408.  
  409.     if(-1 != (sigbit1 = AllocSignal(-1)))
  410.     {
  411.         SetSignal (1 << sigbit1, 1 << sigbit1); // Initial state is "finished"
  412.  
  413.         if(-1 != (sigbit2 = AllocSignal(-1)))
  414.         {
  415.             SetSignal (1 << sigbit2, 1 << sigbit2); // Initial state is "finished"
  416.  
  417.             ok = 1;
  418.         }
  419.     }
  420.  
  421.     return(ok);
  422.  
  423. }
  424.  
  425. /*****************************************************************************/
  426.  
  427. long get_window(void)
  428. {
  429.     long ok = 0;
  430.  
  431.     if (win = OpenWindow(&NewWindowStructure1))
  432.     {
  433.         rp = win->RPort;
  434.         ok = 1;
  435.     }
  436.  
  437.     return(ok);
  438.  
  439. }
  440.  
  441. /*****************************************************************************/
  442.  
  443. void moudrv_read(void)
  444. {
  445.     moudrv_x=win->MouseX;
  446.     moudrv_y=win->MouseY;
  447.     moudrv_but=!(ciamou->ciapra & 0x0040);
  448. }
  449.  
  450. void moudrv_init(void)
  451. {
  452. }
  453.  
  454. void moudrv_update(void)
  455. {
  456. }
  457.  
  458. void moudrv_close(void)
  459. {
  460. }
  461.